/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.catalina.util;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.LifecycleState;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.ExceptionUtils;
import org.apache.tomcat.util.res.StringManager;

/**
 * Base implementation of the {@link Lifecycle} interface that implements the
 * state transition rules for {@link Lifecycle#start()} and
 * {@link Lifecycle#stop()}
 * Lifecycle 接口的基本实现
 * 在Lifecycle中声明了 生命周期的方法 init start stop destory方法
 *                    声明了监听器和相关的事件
 *                    在 LifecycleBase中实现了基本的串联。
 *
 */
public abstract class LifecycleBase implements Lifecycle {

    private static final Log log = LogFactory.getLog(LifecycleBase.class);//日志打印对象。

    private static final StringManager sm = StringManager.getManager(LifecycleBase.class);//国际化字符串对象。


    /**
     * The list of registered LifecycleListeners for event notifications.
     */
    private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();//监听器集合，用于监听生命周期的事件。


    /**
     * The current state of the source component.
     * 记录当前对象状态的实例
     */
    private volatile LifecycleState state = LifecycleState.NEW;//初始的状态是NEW


    private boolean throwOnFailure = true;//失败后是否抛出异常。


    /**
     * Will a {@link LifecycleException} thrown by a sub-class during
     * {@link #initInternal()}, {@link #startInternal()},
     * {@link #stopInternal()} or {@link #destroyInternal()} be re-thrown for
     * the caller to handle or will it be logged instead?
     *
     * @return {@code true} if the exception will be re-thrown, otherwise
     *         {@code false}
     */
    public boolean getThrowOnFailure() {
        return throwOnFailure;
    }


    /**
     * Configure if a {@link LifecycleException} thrown by a sub-class during
     * {@link #initInternal()}, {@link #startInternal()},
     * {@link #stopInternal()} or {@link #destroyInternal()} will be re-thrown
     * for the caller to handle or if it will be logged instead.
     *
     * @param throwOnFailure {@code true} if the exception should be re-thrown,
     *                       otherwise {@code false}
     */
    public void setThrowOnFailure(boolean throwOnFailure) {
        this.throwOnFailure = throwOnFailure;
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public void addLifecycleListener(LifecycleListener listener) {//实现添加监听器对象方法。
        lifecycleListeners.add(listener);
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public LifecycleListener[] findLifecycleListeners() {//实现获取所有监听器对象方法。
        return lifecycleListeners.toArray(new LifecycleListener[0]);
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public void removeLifecycleListener(LifecycleListener listener) {//实现移除监听器对象方法。
        lifecycleListeners.remove(listener);
    }


    /**
     * Allow sub classes to fire {@link Lifecycle} events.
     *     监听器触发相关的事件
     * @param type  Event type  事件类型
     * @param data  Data associated with event. 传递给触发的监听器的数据
     */
    protected void fireLifecycleEvent(String type, Object data) {//实现触发事件并通知监听器对象，type为时间类型，data为事件携带数据。
        LifecycleEvent event = new LifecycleEvent(this, type, data);
        for (LifecycleListener listener : lifecycleListeners) {
            // 遍历获取所有的监听器-->触发
            listener.lifecycleEvent(event);
        }
    }


    /**
     * 实现了 Lifecycle 中定义的init方法
     * 该方法和对应的组件的状态产生的关联
     * 1.具体的组件初始化操作 Server  Service Connector Engine Host Context
     * 2.状态变化
     * 3.事件发布
     * @throws LifecycleException
     */
    @Override
    public final synchronized void init() throws LifecycleException {//实现初始化流程。
        if (!state.equals(LifecycleState.NEW)) {//状态校验，如果当前状态不是NEW，那么就抛出异常。
            // 无效的操作  只有状态为 New 的才能调用init方法进入初始化
            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);//抛出异常。
        }

        try {
            // 设置状态为初始化进行中....同步在方法中会触发对应的事件
            setStateInternal(LifecycleState.INITIALIZING, null, false);//设置INITIALIZING状态，发布BEFORE_INIT_EVENT事件
            initInternal(); // 交给子类具体的实现 初始化操作
            // 更新状态为初始化完成 同步在方法中会触发对应的事件
            setStateInternal(LifecycleState.INITIALIZED, null, false);//设置INITIALIZED状态，发布AFTER_INIT_EVENT事件
        } catch (Throwable t) {
            handleSubClassException(t, "lifecycleBase.initFail", toString());
        }
    }


    /**
     * Sub-classes implement this method to perform any instance initialisation
     * required.
     *
     * @throws LifecycleException If the initialisation fails
     */
    protected abstract void initInternal() throws LifecycleException;//子类实现该方法，完成内部组件初始化操作。


    /**
     * 和 init 方法相识的逻辑，其实就是简化了子类的处理
     *    在本方法中完成了 生命周期方法和相关事件及监听器的处理
     * {@inheritDoc}
     */
    @Override
    public final synchronized void start() throws LifecycleException {//实现开始流程。

        //组件已经处于启动流程中或者已经启动完成时，打印输出。
        if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
                LifecycleState.STARTED.equals(state)) {//状态校验，STARTING_PREP、STARTING、STARTED，意思就是如果处于启动阶段，就不允许再次启动。

            if (log.isDebugEnabled()) {
                Exception e = new LifecycleException();
                log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
            } else if (log.isInfoEnabled()) {
                log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
            }

            return;
        }

        //状态为新建状态，先执行初始化流程。
        if (state.equals(LifecycleState.NEW)) {//如果状态是 NEW，那么就调用 init() 方法进行初始化
            init();
        }
        //状态为失败状态，先执行停止流程。
        else if (state.equals(LifecycleState.FAILED)) {//如果状态是 FAILED，那么就调用 stop() 方法进行停止
            stop();
        }
        //状态不是初始化完成状态且不是停止流程完成状态，抛出无效状态转换异常。
        else if (!state.equals(LifecycleState.INITIALIZED) &&
                !state.equals(LifecycleState.STOPPED)) {//如果状态不是 INITIALIZED、STOPPED，那么就抛出异常
            invalidTransition(Lifecycle.BEFORE_START_EVENT);
        }

        try {
            // 设置状态为启动之前
            setStateInternal(LifecycleState.STARTING_PREP, null, false);//设置STARTING_PREP状态，发布BEFORE_START_EVENT事件。
            // 交给子类来具体的实现
            startInternal();//子类必须把状态修改为STARTING，否则后面的校验会直接抛出异常。如果一切正常，那么状态最终会变成STARTED。
            // 子类处理完成后，子类将组件设置为FAILED时，需要进入停止流程。
            if (state.equals(LifecycleState.FAILED)) {//如果状态是 FAILED，那么就调用 stop() 方法进行停止
                // This is a 'controlled' failure. The component put itself into the
                // FAILED state so call stop() to complete the clean-up.
                stop();
            }
            //如果子类没有开始失败，那么这里的状态应该是STARTING启动状态，如果不是，抛出无效状态转换异常，因为只有STARTING才能转换为STARTED。
            else if (!state.equals(LifecycleState.STARTING)) {//如果状态不是 STARTING，那么就抛出异常
                // Shouldn't be necessary but acts as a check that sub-classes are
                // doing what they are supposed to.
                invalidTransition(Lifecycle.AFTER_START_EVENT);//抛出异常。
            } else {//当前状态为 STARTING，那么就设置状态为 STARTED，发布AFTER_START_EVENT事件。
                //将状态转换为STARTED，表示所有依赖组件均已启动成功。
                setStateInternal(LifecycleState.STARTED, null, false);//那么就设置状态为 STARTED，发布AFTER_START_EVENT事件。
            }
        } catch (Throwable t) {
            // This is an 'uncontrolled' failure so put the component into the
            // FAILED state and throw an exception.
            handleSubClassException(t, "lifecycleBase.startFail", toString());
        }
    }


    /**
     * Sub-classes must ensure that the state is changed to
     * {@link LifecycleState#STARTING} during the execution of this method.
     * Changing state will trigger the {@link Lifecycle#START_EVENT} event.
     *
     * If a component fails to start it may either throw a
     * {@link LifecycleException} which will cause it's parent to fail to start
     * or it can place itself in the error state in which case {@link #stop()}
     * will be called on the failed component but the parent component will
     * continue to start normally.
     *
     * @throws LifecycleException Start error occurred
     */
    protected abstract void startInternal() throws LifecycleException;//由子类实现依赖组件的初始化过程，子类必须将状态转换为STARTING。


    /**
     * {@inheritDoc}
     */
    @Override
    public final synchronized void stop() throws LifecycleException {//实现停止流程。

        //如果已经处于停止流程中，或者已经停止，那么打印异常并返回。
        if (LifecycleState.STOPPING_PREP.equals(state) || LifecycleState.STOPPING.equals(state) ||
                LifecycleState.STOPPED.equals(state)) {//状态校验，如果当前状态是 STOPPING_PREP、STOPPING、STOPPED，那么就直接返回。意思就是出于停止阶段，不允许再次停止。

            if (log.isDebugEnabled()) {
                Exception e = new LifecycleException();
                log.debug(sm.getString("lifecycleBase.alreadyStopped", toString()), e);
            } else if (log.isInfoEnabled()) {
                log.info(sm.getString("lifecycleBase.alreadyStopped", toString()));
            }

            return;
        }

        //当前状态为NEW状态，直接转换为STOPPED，因为此时内部组件都没有启动，所以不需要进入完整的停止周期。
        if (state.equals(LifecycleState.NEW)) {//如果状态是 NEW，直接修改状态为 STOPPED即可，不需要做其他的操作。
            state = LifecycleState.STOPPED;
            return;
        }

        //只能从STARTED和FAILED状态进入停止流程，否则抛出无效状态异常。
        if (!state.equals(LifecycleState.STARTED) && !state.equals(LifecycleState.FAILED)) {//如果状态不是 STARTED、FAILED，那么就抛出异常。只有这两种状态才可以进行停止操作。
            invalidTransition(Lifecycle.BEFORE_STOP_EVENT);
        }

        try {
            //当前状态为FAILED状态，那么触发BEFORE_STOP_EVENT异常通知监听器。
            if (state.equals(LifecycleState.FAILED)) {//如果状态是 FAILED，发布BEFORE_STOP_EVENT事件。
                // Don't transition to STOPPING_PREP as that would briefly mark the
                // component as available but do ensure the BEFORE_STOP_EVENT is
                // fired
                fireLifecycleEvent(BEFORE_STOP_EVENT, null);//发布BEFORE_STOP_EVENT事件。
            } else {
                //否则开始转变状态为STOPPING_PREP。
                setStateInternal(LifecycleState.STOPPING_PREP, null, false);//设置状态为 STOPPING_PREP，发布BEFORE_STOP_EVENT事件。
            }

            //子类使用用于停止依赖的子组件，并将状态修改为STOPPING。
            stopInternal();//交给子类来具体的实现

            // Shouldn't be necessary but acts as a check that sub-classes are
            // doing what they are supposed to.
            //子类需要转变状态为STOPPING，或者进入FAILED状态，否则抛出无效状态转换异常。
            if (!state.equals(LifecycleState.STOPPING) && !state.equals(LifecycleState.FAILED)) {//如果状态不是 STOPPING、FAILED，那么就抛出异常。
                invalidTransition(Lifecycle.AFTER_STOP_EVENT);
            }

            //将状态修改为STOPPED。
            setStateInternal(LifecycleState.STOPPED, null, false);//设置状态为 STOPPED，发布AFTER_STOP_EVENT事件。
        } catch (Throwable t) {
            handleSubClassException(t, "lifecycleBase.stopFail", toString());
        } finally {
            if (this instanceof Lifecycle.SingleUse) {
                // Complete stop process first
                //子类实现了SingleUse，表明对象只使用一次，那么在stop方法返回后，将自动调用destroy方法，进入销毁流程。
                setStateInternal(LifecycleState.STOPPED, null, false);//设置状态为 STOPPED，发布AFTER_STOP_EVENT事件。
                destroy();
            }
        }
    }


    /**
     * Sub-classes must ensure that the state is changed to
     * {@link LifecycleState#STOPPING} during the execution of this method.
     * Changing state will trigger the {@link Lifecycle#STOP_EVENT} event.
     *
     * @throws LifecycleException Stop error occurred
     */
    protected abstract void stopInternal() throws LifecycleException;//实现依赖组件的停止操作，负责将状态转变为STOPPING。


    @Override
    public final synchronized void destroy() throws LifecycleException {//失效销毁流程。
        //当前状态为FAILED状态，先执行stop流程，因为此时可能有组件已经开始运行，但是由于某些原因导致进入FAILED状态，所以有必要进入stop流程。
        if (LifecycleState.FAILED.equals(state)) {//如果状态是 FAILED，那么就调用 stop() 方法。
            try {
                // Triggers clean-up
                stop();
            } catch (LifecycleException e) {
                // Just log. Still want to destroy.
                log.error(sm.getString("lifecycleBase.destroyStopFail", toString()), e);
            }
        }

        //如果已经销毁或者处于销毁流程中，那么打印异常并退出。
        if (LifecycleState.DESTROYING.equals(state) || LifecycleState.DESTROYED.equals(state)) {//如果状态是 DESTROYING、DESTROYED，那么就直接返回。
            if (log.isDebugEnabled()) {
                Exception e = new LifecycleException();
                log.debug(sm.getString("lifecycleBase.alreadyDestroyed", toString()), e);
            } else if (log.isInfoEnabled() && !(this instanceof Lifecycle.SingleUse)) {
                // Rather than have every component that might need to call
                // destroy() check for SingleUse, don't log an info message if
                // multiple calls are made to destroy()
                log.info(sm.getString("lifecycleBase.alreadyDestroyed", toString()));
            }

            return;
        }

        //当前状态不是STOPPED、FAILED、NEW、INITIALIZED，抛出无效状态转换异常，因为只有这4种状态可以直接进入销毁流程。
        if (!state.equals(LifecycleState.STOPPED) && !state.equals(LifecycleState.FAILED) &&
                !state.equals(LifecycleState.NEW) && !state.equals(LifecycleState.INITIALIZED)) {//如果状态不是 STOPPED、FAILED、NEW、INITIALIZED，那么就抛出异常。
            invalidTransition(Lifecycle.BEFORE_DESTROY_EVENT);
        }

        try {
            //状态转变为DESTROYING，子类执行依赖组件的销毁操作，然后再将状态转变为DESTROYED。
            setStateInternal(LifecycleState.DESTROYING, null, false);//设置状态为 DESTROYING，发布BEFORE_DESTROY_EVENT事件。
            destroyInternal();//交给子类来具体的实现
            setStateInternal(LifecycleState.DESTROYED, null, false);//设置状态为 DESTROYED，发布AFTER_DESTROY_EVENT事件。
        } catch (Throwable t) {
            handleSubClassException(t, "lifecycleBase.destroyFail", toString());
        }
    }


    /**
     * Sub-classes implement this method to perform any instance destruction
     * required.
     *
     * @throws LifecycleException If the destruction fails
     */
    protected abstract void destroyInternal() throws LifecycleException;//子类实现依赖组件的销毁操作。


    /**
     * {@inheritDoc}
     */
    @Override
    public LifecycleState getState() {//实现获取当前状态。
        return state;
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public String getStateName() {//实现获取当前状态名。
        return getState().toString();
    }


    /**
     * Provides a mechanism for sub-classes to update the component state.
     * Calling this method will automatically fire any associated
     * {@link Lifecycle} event. It will also check that any attempted state
     * transition is valid for a sub-class.
     *
     * @param state The new state for this component
     * @throws LifecycleException when attempting to set an invalid state
     */
    protected synchronized void setState(LifecycleState state) throws LifecycleException {//用于设置当前组件状态。
        setStateInternal(state, null, true);
    }


    /**
     * Provides a mechanism for sub-classes to update the component state.
     * Calling this method will automatically fire any associated
     * {@link Lifecycle} event. It will also check that any attempted state
     * transition is valid for a sub-class.
     *
     * @param state The new state for this component
     * @param data  The data to pass to the associated {@link Lifecycle} event
     * @throws LifecycleException when attempting to set an invalid state
     */
    protected synchronized void setState(LifecycleState state, Object data)
            throws LifecycleException {//用于设置当前组件状态，可以携带通知监听器的数据。
        setStateInternal(state, data, true);
    }


    private synchronized void setStateInternal(LifecycleState state, Object data, boolean check)
            throws LifecycleException {//用于设置当前组件状态，可以携带通知监听器的数据，并且设置是否检查当前状态合法性。data为携带数据，check表示是否检测组件状态合法性。

        if (log.isDebugEnabled()) {
            log.debug(sm.getString("lifecycleBase.setState", this, state));
        }

        if (check) {
            // Must have been triggered by one of the abstract methods (assume
            // code in this class is correct)
            // null is never a valid state
            if (state == null) {
                //state不允许是null。
                invalidTransition("null");
                // Unreachable code - here to stop eclipse complaining about
                // a possible NPE further down the method
                return;
            }

            // Any method can transition to failed
            // startInternal() permits STARTING_PREP to STARTING
            // stopInternal() permits STOPPING_PREP to STOPPING and FAILED to
            // STOPPING
            //任何方法都可以将状态转变为FAILED，因为任何方法的调用都可能出错。startInternal()方法允许将状态从STARTING_PREP转变为STARTDING，stopInternal()方法允许将状态从STOPPING_PREP转变为STOPPING，或者从FAILED转变为STOPPING。
            if (!(state == LifecycleState.FAILED ||
                    (this.state == LifecycleState.STARTING_PREP &&
                            state == LifecycleState.STARTING) ||
                    (this.state == LifecycleState.STOPPING_PREP &&
                            state == LifecycleState.STOPPING) ||
                    (this.state == LifecycleState.FAILED &&
                            state == LifecycleState.STOPPING))) {
                // No other transition permitted
                //其他的状态转变方式都不支持。
                invalidTransition(state.name());
            }
        }

        //否则将当前状态设置为传入状态。
        this.state = state; // 修改当前对象的状态
        // 根据状态和事件的绑定关系获取对应的事件
        String lifecycleEvent = state.getLifecycleEvent();//获取时间字符串对象后，将事件发送到监听器中。
        if (lifecycleEvent != null) {
            // 发布对应的事件  获取所有的监听器，执行触发的方法
            fireLifecycleEvent(lifecycleEvent, data);
        }
    }


    private void invalidTransition(String type) throws LifecycleException {//抛出无效状态异常，type为异常类型。
        String msg = sm.getString("lifecycleBase.invalidTransition", type, toString(), state);
        throw new LifecycleException(msg);
    }


    private void handleSubClassException(Throwable t, String key, Object... args) throws LifecycleException {//在发生异常时，处理异常。
        //将状态修改为FAILED。
        setStateInternal(LifecycleState.FAILED, null, false);
        ExceptionUtils.handleThrowable(t);
        //根据key和args生成异常信息。
        String msg = sm.getString(key, args);
        //如果涉及在失败时抛出了异常，即设置throwOnFailure位true，那么抛出异常，否则只打印异常信息。
        if (getThrowOnFailure()) {
            if (!(t instanceof LifecycleException)) {
                t = new LifecycleException(msg, t);
            }
            throw (LifecycleException) t;
        } else {
            log.error(msg, t);
        }
    }
}
